package com.example.entity.factory;

import java.util.Calendar;

import com.example.constant.MessageConstant;
import com.example.constant.MessageTypeConstant;
import com.example.entity.body.impl.ASDUBody;
import com.example.entity.factory.impl.UnpooledMessageFactory;
import com.example.entity.header.Header;
import com.example.entity.message.Message;
import com.example.entity.message.impl.ErrorMessage;
import com.example.entity.message.impl.InitMessage;
import com.example.entity.message.impl.RemoteElectricAffirmMessage;
import com.example.entity.message.impl.RemoteElectricMessage;
import com.example.util.EncodeUtil;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;

public class Unpooled {
	public static MessageFactory factory = UnpooledMessageFactory.DEFAULT;

	public static Message newInitMessage() {
		// TODO Auto-generated method stub
		return factory.newInitMessage();
	}

	public static Message newUMessage3() {
		// TODO Auto-generated method stub
		return factory.newUMessage3();
	}

	public static Message newUMessage4() {
		// TODO Auto-generated method stub
		return factory.newUMessage4();
	}

	public static Message newCallMessage() {
		// TODO Auto-generated method stub
		return factory.newCallMessage();
	}

	public static Message newCountMessage() {
		// TODO Auto-generated method stub
		return factory.newCountMessage();
	}

	public static Message newTimeSynMessage() throws Exception {
		// TODO Auto-generated method stub
		Calendar calendar = Calendar.getInstance();
		byte[] key = { 0, 0, 0 };
		byte[] value = new byte[7];
		// yy
		value[6] = (byte) (calendar.get(Calendar.YEAR) - 2000);
		// MM
		value[5] = (byte) calendar.get(Calendar.MONTH);
		// DD
		byte DD = (byte) calendar.get(Calendar.DATE);
		// week
		byte week = (byte) calendar.get(Calendar.DAY_OF_WEEK);

		value[4] = (byte) ((week << 5) & DD);
		// HH
		value[3] = (byte) calendar.get(Calendar.HOUR_OF_DAY);
		// mm
		value[2] = (byte) calendar.get(Calendar.MINUTE);
		// Mi
		char mi = (char) calendar.get(Calendar.MILLISECOND);
		// Mi 1
		value[1] = (byte) (mi >>> 8);
		// Mi 0
		value[0] = (byte) mi;

		ByteBuf buf = io.netty.buffer.Unpooled.buffer();
		buf.writeBytes(key);
		buf.writeBytes(value);

		Message message = factory.newTimeSynMessage();
		message.setAttachment(buf);

		return message;
	}

	public static Message newErrorMessage() {
		// TODO Auto-generated method stub
		return factory.newErrorMessage();
	}

	public static Message wrapperInitMessage(ByteBuf buf) {
		return new InitMessage(buf);
	}

	public static Message wrapper(ByteBuf frame) {
		Header header = new Header();
		header.setContextLength(frame.readableBytes());
		header.setUControlField(frame.readInt());
		char type = (char) frame.readByte();
		int qdsPolicy = getQDSPolicy(type);
		int valuePolicy = getValuePolicy(type);
		Message message = new Message();

		ASDUBody body = new ASDUBody(type, frame, valuePolicy, qdsPolicy);

		message.setHeader(header);
		message.setBody(body);

		return message;
	}

	public static Message wrapperErrorMessage(int errorType) throws Exception {
		ByteBuf buf = io.netty.buffer.Unpooled.buffer();
		byte[] bs = { 0, 0, 1 };
		buf.writeBytes(bs);
		buf.writeInt(errorType);

		ErrorMessage errorMessage = new ErrorMessage();
		errorMessage.setAttachment(buf);
		return errorMessage;
	}

	public static Message wrapperRemoteElectricMessage(String equipmentID, byte interfaceID, int remaming,
			String userID, byte electricWay, float parameterSrc) throws Exception {
		ByteBuf buf = io.netty.buffer.Unpooled.buffer();
		byte[] bs = { 0, 0, 1 };
		buf.writeBytes(bs);
		buf.writeByte(MessageConstant.RECORD_NUMBER);
		buf.writeBytes(EncodeUtil.BCDEncode(equipmentID));
		buf.writeByte(interfaceID);
		buf.writeInt(remaming);
		buf.writeBytes(EncodeUtil.BCDEncode(userID));
		buf.writeByte(electricWay);

		// 参数最大为9999.99
		String parameter = Integer.toString(Math.round(parameterSrc * 100));
		char[] cs = parameter.toCharArray();
		char[] parameterChars = new char[6];
		for (int i = 0; i < 6; i++) {
			parameterChars[i] = 0;
		}

		for (int i = 5, j = cs.length - 1; i >= 0 && j >= 0; i--, j--) {
			parameterChars[i] = (char) (cs[j] - 48);
		}
		bs = new byte[3];
		for (int i = 0, j = 0; i < 3; i++, j += 2) {
			bs[i] = (byte) ((parameterChars[j] << 4) | (parameterChars[j + 1]));
		}
		buf.writeBytes(bs);

		RemoteElectricMessage electricMessage = new RemoteElectricMessage();
		electricMessage.setAttachment(buf);
		return electricMessage;

	}

	public static Message wrapperRemoteElectricAffirmMessage(String equipmentID) throws Exception {
		RemoteElectricAffirmMessage remoteElectricAffirmMessage = new RemoteElectricAffirmMessage();
		ByteBuf buf = io.netty.buffer.Unpooled.buffer();
		byte[] messageObjectAddr = { 0x0, 0x7, (byte) 0xe2 };
		buf.writeBytes(messageObjectAddr);
		buf.writeByte(0x3);
		buf.writeBytes(EncodeUtil.BCDEncode(equipmentID));
		remoteElectricAffirmMessage.setAttachment(buf);
		buf.release();
		return remoteElectricAffirmMessage;

	}

	public static void main(String[] args) {
		float parameterSrc = 9999.99f;
		String parameter = Integer.toString(Math.round(parameterSrc * 100));
		char[] cs = parameter.toCharArray();
		char[] parameterChars = new char[6];
		for (int i = 0; i < 6; i++) {
			parameterChars[i] = 0;
		}

		for (int i = 5, j = cs.length - 1; i >= 0 && j >= 0; i--, j--) {
			parameterChars[i] = (char) (cs[j] - 48);
		}

		byte[] bs = new byte[3];
		for (int i = 0, j = 0; i < 3; i++, j += 2) {
			System.out.println(
					Integer.toHexString(parameterChars[j] << 4) + " " + Integer.toHexString(parameterChars[j + 1]));
			bs[i] = (byte) ((parameterChars[j] << 4) | (parameterChars[j + 1]));
		}

		for (byte b : bs) {
			System.out.println(Integer.toHexString(b));
		}
	}

	/**
	 * 根据消息类型进行qds描述的判断
	 * 
	 * @param type
	 *            消息的类型
	 * @return 是否有qds描述
	 */
	private static int getQDSPolicy(char type) {
		if (type == MessageTypeConstant.CALLED_RESPONED_MESSAGE01
				|| type == MessageTypeConstant.CALLED_RESPONED_MESSAGE02
				|| type == MessageTypeConstant.CALLED_RESPONED_MESSAGE03) {
			return 1;
		}
		return 0;
	}

	/**
	 * 判断是否为总召回应第一类型，仅有的无value类型
	 * 
	 * @param type
	 *            信息类型
	 * @return value策略
	 */
	public static int getValuePolicy(char type) {
		if (type == MessageTypeConstant.CALLED_RESPONED_MESSAGE01) {
			return MessageConstant.NOVALUE;
		}
		return MessageConstant.HASVAlUE;
	}

}
